﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cephei.Core.Generic;
using Microsoft.FSharp.Control;
using Microsoft.FSharp.Core;

namespace Cephei.Core
{
    /// <summary>
    /// Abstract factory interface for creating Cells
    /// </summary>
    public interface ICell_Factory
    {
        /// <summary>
        /// Create a generic cell
        /// </summary>
        /// <typeparam name="T">type of the value held within the Cell</typeparam>
        /// <returns>a new generic Cell</returns>
        ICell<T> Create<T> ();

        /// <summary>
        /// Create a generic cell with the attached value
        /// </summary>
        /// <typeparam name="T">type held within the cell</typeparam>
        /// <param name="t">the value that is the source of the cell</param>
        /// <returns></returns>
        ICell<T> Create<T> (T t);

        /// <summary>
        /// Create a generic cell within the model with the mnmonic
        /// </summary>
        /// <typeparam name="T">type of the value held within the Cell</typeparam>
        /// <param name="model">the model dictionary that the cell is being created in </typeparam>
        /// <param name="mnmonic">the mnmonic to identify this cell</typeparam>
        /// <returns>a new generic Cell</returns>
        ICell<T> Create<T> (IModel model, string mnmonic);

        /// <summary>
        /// Create a generic cell with the attached value
        /// </summary>
        /// <typeparam name="T">type held within the cell</typeparam>
        /// <param name="t">the value that is the source of the cell</param>
        /// <param name="model">the model dictionary that the cell is being created in </typeparam>
        /// <param name="mnmonic">the mnmonic to identify this cell</typeparam>
        /// <returns></returns>
        ICell<T> Create<T> (T t, IModel model, string mnmonic);

        /// <summary>
        /// Create an empty Cell with the attached mnmonic.
        /// </summary>
        /// <remarks>
        /// I you wish to reference a cell before it has been defined, an empty cell cal hold the 
        /// the dependancy tree until the definition transfers it to a new object
        /// </remarks>
        /// <param name="model">the model dictionary that the cell is being created in </typeparam>
        /// <param name="mnmonic">the mnmonic to identify this cell</typeparam>
        /// <returns></returns>
        ICell Create (IModel model, string mnmonic);

        /// <summary>
        /// Create a generic Cell with the formula for calculation
        /// </summary>
        /// <typeparam name="T">type held within the cell</typeparam>
        /// <param name="async">the FSharp function delegate to use as a formula</param>
        /// <returns>a new generic cell</returns>
        /// <remarks>
        /// Explicit name aid F# deduction of type
        /// </remarks>
        ICoCell<T> CreateFunc<T> (FSharpFunc<Unit, T> fastfunc);

        /// <summary>
        /// Create a generic Cell with the formula for calculation
        /// </summary>
        /// <typeparam name="T">type held within the cell</typeparam>
        /// <param name="async">the FSharp function delegate to use as a formula</param>
        /// <returns>a new generic cell</returns>
        /// <param name="model">the model dictionary that the cell is being created in </typeparam>
        /// <param name="mnmonic">the mnmonic to identify this cell</typeparam>
        /// <remarks>
        /// Explicit name aid F# deduction of type
        /// </remarks>
        ICoCell<T> CreateFunc<T> (FSharpFunc<Unit, T> fastfunc, IModel model, string mnmonic);
    }
}
